<template>
  <a-modal
    width="90%"
    class="approval"
    centered
    :bodyStyle="{ padding: 0, overflowY: 'auto', height: bodyHeight }"
    :title="title"
    :footer="null"
    destroyOnClose
    v-model="isVisible"
  >
    <a-tabs class="approval-tabs" tab-position="left" :defaultActiveKey="activePane">
      <a-tab-pane class="approval-content" tab="提交资料" key="1">
        <!-- <component :is="detailComponent" :dataId="bizId" v-model="dataSouces" :editable="false"></component> -->
        <keep-alive>
          <component
            ref="formModel"
            isFlow
            :is="asyncComponent"
            :dataId="bizId"
            v-model="dataSouces"
            :editable="editable"
            :ditableFiexd="ditableFiexd"
          ></component>
        </keep-alive>
      </a-tab-pane>
      <a-tab-pane class="approval-content" tab="审批处理" key="2">
        <a-form>
          <!-- 处理结果 -->
          <a-form-item
            label="处理结果:"
            :labelCol="{ lg: { span: 6 }, sm: { span: 6 } }"
            :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
            :required="false"
          >
            <a-radio-group v-model="currentWorkflow">
              <a-radio v-for="(item, key) of workflow" :key="key" :value="key">{{ item.lineName || '通过' }}</a-radio>
            </a-radio-group>
          </a-form-item>

          <!-- 处理意见 -->
          <a-form-item
            label="处理意见:"
            :labelCol="{ lg: { span: 6 }, sm: { span: 6 } }"
            :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
          >
            <a-textarea rows="4" :maxLength="255" placeholder="请输入处理意见" v-model="processData.opinion" />
          </a-form-item>

          <!-- 补充字段 -->
          <a-form-item
            v-for="(item, index) of taskField"
            :key="item.id + index"
            :label="item.fieldTitle"
            :labelCol="{ lg: { span: 6 }, sm: { span: 6 } }"
            :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
          >
            <a-input v-if="item.fieldType == 'int' || item.fieldType == 'double'" type="number" v-model="item.value" />
            <a-input v-if="item.fieldType == 'string'" type="text" v-model="item.value" />

            <a-radio-group v-if="item.fieldType == 'radio'" v-model="item.value">
              <a-radio v-for="(opt, key) of item.options" :key="key" :value="opt.value">{{ opt.label }}</a-radio>
            </a-radio-group>

            <a-checkbox-group v-if="item.fieldType == 'checkbox'" :options="item.options" v-model="item.value" />

            <a-select v-if="item.fieldType == 'select'" v-model="item.value">
              <a-select-option v-for="(opt, key) of item.options" :key="key" :value="opt.value">
                {{ opt.label }}
              </a-select-option>
            </a-select>
          </a-form-item>

          <!-- 下一步 -->
          <template
            v-if="nextProcess.taskNodeList && nextProcess.taskNodeList.length && nextProcess.lineName != '完成'"
          >
            <!-- <a-form-item
              label="下一步事务:"
              :labelCol="{ lg: { span: 6 }, sm: { span: 6 } }"
              :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
              >
            </a-form-item> -->
            <!-- 审批人 -->
            <template v-for="(item, index) of nextProcess.taskNodeList">
              <a-form-item
                :label="item.taskName + '处理人:'"
                :labelCol="{ lg: { span: 6 }, sm: { span: 6 } }"
                :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
                :key="index"
                v-if="item.taskName"
              >
                <!-- <x-user-tree
                  v-model="item.handlerId"
                  :text="item.handlerName"
                  :multi="Boolean(item.isMultiInstance)"
                  :disabled="!item.canChooseHandler"
                  :params="{ taskId: item.taskKey }"
                ></x-user-tree> -->
                <x-select-user-by-dep v-model="item.handlerId" :params="{ taskId: item.taskKey }" :multi="Boolean(item.isMultiInstance)" :disabled="!item.canChooseHandler"></x-select-user-by-dep>
              </a-form-item>
            </template>
          </template>

          <!-- 提交 -->
          <a-form-item :wrapperCol="{ span: 24 }" style="text-align: center">
            <a-button htmlType="submit" type="primary" @click="submit">提交</a-button>
          </a-form-item>
        </a-form>
      </a-tab-pane>

      <a-tab-pane forceRender class="approval-content" tab="审批记录" key="3">
        <s-table ref="table" rowKey="key" :columns="columns" :data="loadRecords" :pagination="null"></s-table>
      </a-tab-pane>

      <a-tab-pane forceRender class="approval-content" tab="审批流程" key="4">
        <img :src="processImage" />
      </a-tab-pane>
    </a-tabs>
  </a-modal>
</template>

<script>
import { merge } from 'lodash'
import { axios } from '@/utils/request'
import STable from '@/components/table/'
import XUserTree from '@/components/extends/XUserTree'
import XSelectUserByDep from '@/components/extends/XSelectUserByDep'
import { getWorkflow } from '@/api/api'
import { getAction, postAction } from '@/api/manage'
function arrayBufferToBase64(buffer) {
  var binary = ''
  var bytes = new Uint8Array(buffer)
  var len = bytes.byteLength
  for (var i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i])
  }
  return window.btoa(binary)
}
export default {
  components: {
    STable,
    XUserTree,
    XSelectUserByDep
  },
  model: {
    prop: 'visible',
    event: 'input'
  },
  props: {
    title: {
      type: String,
      default: '审批'
    },
    visible: Boolean,
    businessUrl: String, //业务链接
    bizId: String, //业务ID
    detailComponent: String, //业务组件
    ditableFiexd: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data() {
    return {
      basePath: window._CONFIG['domianURL'],
      editable: false,
      processImage: '',
      urlMap: {
        VolunteerTeam: '/volunteerTeam/add',
        VolunteerTeamMember: '/volunteerTeamUser/add',
        Society: '/org/society/add',
        SocietyMember: '/org/societyUser/add',
        Organization: '/org/stdGroup/add',
        OrganizationMember: '/org/stdGroupUser/add',
        ProjectBuild: '/researchProject/add',
        ProjectReview: '/researchProjectReview/add',
        FundApplyForm: '/fundApply/add',
        MaterialApplyForm: '/materialApply/add',
        HonorForm: '/gloryApply/add'
      },
      activePane: '1',
      dataSouces: {},
      fieldList: [],
      taskField: [],
      workflow: [],
      currentWorkflow: 0,
      processData: {},
      isVisible: false,
      bodyHeight: '',
      users: '',
      columns: [
        {
          title: '任务名称',
          dataIndex: 'taskName',
          width: 160
        },
        {
          title: '处理人',
          dataIndex: 'dealUserName',
          width: 160
        },
        {
          title: '处理时间',
          dataIndex: 'dealTime',
          width: 180
        },
        {
          title: '审批意见',
          dataIndex: 'opinion',
          width: 260
        },
        {
          title: '审批结果',
          dataIndex: 'result',
          width: 160
        }
      ],
      // 加载数据方法 必须为 Promise 对象
      loadRecords: parameter => {
        return getAction('/workflow/queryProcessRecordByBizId', {
          bizId: this.bizId
        }).then(res => {
          if (res.success && res.result) {
            let records = res.result.records.map((item, key) => {
              return {
                key: key,
                ...item
              }
            })
            const obj = {
              data: records || [],
              pageNo: res.result.current,
              pageSize: res.result.size,
              totalCount: res.result.total,
              totalPage: res.result.page,
              sortColumns: res.result.sortColumns
            }
            return obj
          } else {
            return {}
          }
        })
      }
    }
  },
  computed: {
    asyncComponent() {
      var compMap = {
        VolunteerTeam: '/volunteer/modules/VolunteerTeam',
        VolunteerTeamMember: '/volunteer/modules/Volunteer',
        Society: '/society/modules/Society',
        SocietyMember: '/society/modules/JoinSociety',
        Organization: '/organization/modules/Organization',
        OrganizationMember: '/organization/modules/JoinOrganization',
        ProjectBuild: '/project/modules/ProjectBuild',
        ProjectReview: '/project/modules/ProjectReview',
        FundApplyForm: '/funds/modules/FundApplyForm',
        MaterialApplyForm: '/material/modules/MaterialApplyForm',
        HonorForm: '/honor/modules/HonorForm'
      }
      var compUrl = compMap[this.detailComponent]
      var detailComponent = ''
      if (compUrl) {
        try {
          detailComponent = () => import(`../../views${compUrl}.vue`)
        } catch (error) {
          console.log(error)
        }
      }
      return detailComponent
    },
    nextProcess() {
      let data = this.workflow[this.currentWorkflow] || {}
      if (data && data.taskNodeList) {
        for (let task of data.taskNodeList) {
          if (task.taskName) {
            task.handlerId = task.defaultHandlerId
            task.handlerName = task.defaultHandlerName
          }
        }
      }
      return data
    },
    workflowModel() {
      if (this.nextProcess) {
        var variable = {}
        //${}表达式过滤
        var reg = /[^\{\}]+(?=\})/g
        //处理结果表达式
        var deal = this.nextProcess.conditionExpression ? this.nextProcess.conditionExpression.match(reg) : ''
        if (this.nextProcess.conditionExpression) {
          for (let item of deal) {
            item = item && item.split('==')
            Array.isArray(item) && (variable[item[0]] = item[1])
          }
        }
        //审批人表达式
        for (let task of this.nextProcess.taskNodeList) {
          if (task.handlerUsersExpression) {
            var users = task.handlerUsersExpression.match(reg)
            for (let item of users) {
              item = item && item.split('=')
              Array.isArray(item) && (variable[item[0]] = task.handlerId || '')
            }
          }
        }
        let taskField = {}
        this.taskField.forEach(item => {
          taskField[item.fieldName] = item.value
        })
        return {
          operation: 'submit',
          opinion: this.processData.opinion || '',
          result: this.nextProcess.lineName,
          variable: variable,
          taskField,
          taskHandler: null
        }
      } else {
        return {}
      }
    }
  },
  watch: {
    fieldList: {
      handler(nv, ov) {
        let fieldList = merge([], nv)
        if (fieldList.length) {
          this.taskField = fieldList.map(item => {
            let options = []
            if (['radio', 'checkbox', 'select'].includes(item.fieldType)) {
              var obj = JSON.parse(item.fieldData)
              for (let k of Object.keys(obj)) {
                options.push({
                  label: k,
                  value: obj[k]
                })
              }
            }
            return {
              ...item,
              options,
              value: item.fieldType=='checkbox'?[]:''
            }
          })
        }
      },
      immediate: true
    },
    visible: {
      handler(nv, ov) {
        this.isVisible = nv
        if (nv) {
          this.loadData()
        } else {
          this.processData = {}
          this.currentWorkflow = 0
        }
      },
      immediate: true
    },
    isVisible(nv, ov) {
      this.$emit('input', nv)
    },
    bizId(nv, ov) {
      this.getProcessImage()
    }
  },
  beforeMount() {
    this.bodyHeight = document.body.offsetHeight - 100 + 'px'
  },
  methods: {
    submit() {
      this.$nextTick(() => {
        if (this.currentWorkflow == undefined) {
          return this.$message.warning('请选择处理结果')
        }
        if (!this.isHanlderPass()) {
          return this.$message.warning('请选择处理人')
        }
        this.$refs.formModel.form &&
          this.$refs.formModel.form.validateFields((err, values) => {
            if (!err) {
              const data = merge({}, this.dataSouces, values, {
                workflowModel: this.workflowModel
              })
              if (this.urlMap[this.detailComponent]) {
                postAction(this.urlMap[this.detailComponent], data).then(res => {
                  if (res.success) {
                    this.isVisible = false
                    this.$notification.success({
                      message: '提交成功'
                    })
                    this.$emit('ok', res.message)
                    this.currentWorkflow = 0
                  } else {
                    this.$message.error(res.message)
                  }
                })
              }
            } else {
              this.$message.warning('请检查提交资料表单！')
            }
          })
      })
    },
    loadData() {
      this.activePane = '1'
      getWorkflow({ bizId: this.bizId }).then(res => {
        if (!res.result) return
        this.fieldList = res.result.taskFieldList || []
        this.workflow = res.result.taskLineList || []
        this.editable = res.result.editFlag ? true : false
      })
      this.$nextTick(() => {
        this.$refs.table.refresh()
        this.getProcessImage()
      })
    },
    getProcessImage() {
      axios
        .get('/workflow/showProcessImageByBizId', {
          params: {
            bizId: this.bizId
          },
          responseType: 'blob'
        })
        .then(data => {
          this.processImage = URL.createObjectURL(data)
        })
    },
    show(uname) {
      this.isVisible = true
    },
    handleCancel() {
      this.close()
    },
    close() {
      this.$emit('close')
      this.isVisible = false
    },
    isHanlderPass() {
      let isPass = true
      for (let task of this.nextProcess.taskNodeList) {
        if (task.taskName && !task.handlerId) {
          isPass = false
        } else {
          isPass = true
        }
      }
      return isPass
    }
  }
}
</script>

<style lang="less" scoped>
.approval {
  .approval-tabs {
    height: 100%;
    display: flex;
  }
  .approval-content {
    padding: 0;
  }
  /deep/.ant-tabs-left-content {
    position: relative;
    flex: 1;
    padding: 20px !important;
    margin: 0 !important;
    box-sizing: border-box;
    overflow: auto;
  }
}
</style>
